package com.team.childapp.http.base

import android.text.TextUtils
import com.google.gson.Gson
import com.lzy.okgo.OkGo
import com.lzy.okgo.convert.StringConvert
import com.lzy.okgo.model.HttpParams
import com.lzy.okgo.model.Response
import com.lzy.okrx2.adapter.ObservableResponse
import com.team.childapp.base.App
import com.team.childapp.config.BaseConfig
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import java.io.File

/**
 * Create on: 2025/1/2
 * by Mr.Zhu
 * Description: TODO
 */
open class AppBaseLogical : BaseLogical() {


    /**
     * post 请求
     * content type   json
     *
     * @param url
     * @param obj
     * @param observer
     */
    override fun requestStringForPostNew(
        url: String?,
        obj: Any,
        observer: Observer<Response<String>>?
    ) {
        val map = obj as? Map<*, *> ?: run {
            // 处理转换失败的情况，例如抛出异常或返回默认值
            throw IllegalArgumentException("Parameter 'obj' must be a Map<String, String>")
        }
        //添加公共参数....source=android&appVersion=100&
        val params: MutableMap<Any, Any> = HashMap()
        for ((key, value) in map) {
            params[key as Any] = value as Any
        }

        val token = App.application().getShareData().getString(BaseConfig.TOKEN_ID,"") as String
        val json = "application/json; charset=utf-8".toMediaTypeOrNull()
        val body = RequestBody.create(json, Gson().toJson(params))
        OkGo.post<String>(url)
            .converter(StringConvert())
            .upRequestBody(body)
            .headers("appType", "android")
            .headers("Authorization", "Bearer $token")
            .adapt(ObservableResponse())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer!!)
    }

    /**
     * 登录请求
     * content type   json
     *
     * @param url
     * @param obj
     * @param observer
     */
    protected fun requestStringForLogin(
        url: String?,
        obj: Any,
        observer: Observer<Response<String>>?
    ) {
        val map = obj as Map<String, String>
        val params = HttpParams()
        for ((key, value) in map) {
            params.put(key, value)
        }
        val token = App.application().getShareData().getString(BaseConfig.TOKEN_ID,"") as String
        OkGo.get<String>(url)
            .converter(StringConvert())
            .params(params)
            .headers("Authorization", "Bearer $token")
            .adapt(ObservableResponse())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer!!)
    }


    /**
     * post请求
     *
     * @param url
     * @param obj
     * @param observer
     */
    override fun requestStringForPost(
        url: String?,
        obj: Any,
        observer: Observer<Response<String>>?
    ) {
//        super.requestStringForPost(url, obj, observer);
        val map = obj as Map<String, String>
        //添加公共参数....source=android&appVersion=100&
        val params: MutableMap<Any, Any> = HashMap()
        for ((key, value) in map) {
            params[key] = value
        }
        val tokenID = App.application().getShareData().getString(BaseConfig.TOKEN_ID,"") as String
        val tokenType = App.application().getShareData().getString(BaseConfig.TOKEN_TYPE,"") as String
        OkGo.post<String>(url)
            .converter(StringConvert())
            .headers("blade-auth", "$tokenType $tokenID")
            .upJson(Gson().toJson(params))
            .adapt(ObservableResponse())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer!!)
    }

    override fun requestStringForPostParam(
        url: String?,
        obj: Any,
        observer: Observer<Response<String>>?
    ) {
        val map = obj as Map<String, String>
        val params = HttpParams()
        for ((key, value) in map) {
            params.put(key, value)
        }
        val tokenID = App.application().getShareData().getString(BaseConfig.TOKEN_ID,"") as String
        val tokenType = App.application().getShareData().getString(BaseConfig.TOKEN_TYPE,"") as String
        OkGo.post<String>(url)
            .converter(StringConvert())
            .params(params)
            .headers("blade-auth", "$tokenType $tokenID")
            .adapt(ObservableResponse())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer!!)
    }


    /**
     * get请求获取数据--无参数
     *
     * @param url
     */
    fun requestStringForGet(url: String?, observer: Observer<Response<String>>?) {
        val tokenID = App.application().getShareData().getString(BaseConfig.TOKEN_ID,"") as String
        OkGo.get<String>(url)
            .converter(StringConvert())
            .headers("Authorization", "Bearer $tokenID")
            .adapt<Observable<Response<String>>>(ObservableResponse<String>())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer!!)
    }

    /**
     * get请求获取数据，需要登录后
     *
     * @param url
     */
    fun requestForGetLogin(
        url: String,
        params: Map<String?, String?>,
        observer: Observer<Response<String>>?
    ) {
        val requestUrl = sendGetRequest(url, params)
        requestStringForGet(requestUrl, observer)
    }

    fun sendGetRequest(baseUrl: String, params: Map<String?, String?>): String {
        val query = StringBuilder()
        val entrySet = params.entries
        for ((key, value) in entrySet) {
            if (query.length > 0) {
                query.append("&")
            }
            query.append(key).append("=").append(value)
        }
        val urlString = "$baseUrl?$query"
        return urlString
    }

    /**
     * 上传文件
     *
     * @param url
     * @param mSelectList
     * @param observer
     */
    fun requestFileForPost(
        url: String?,
        mSelectList: List<String?>,
        content: String?,
        observer: Observer<Response<String>>?
    ) {
        val tokenID = App.application().getShareData().getString(BaseConfig.TOKEN_ID,"") as String
        val fileList: MutableList<File> = ArrayList()
        for (path in mSelectList) {
            if (TextUtils.isEmpty(path)) {
                continue
            }
            val file = File(path)
            fileList.add(file)
        }
        OkGo.post<String>(url)
            .converter(StringConvert())
            .isMultipart(true)
            .params("content", content)
            .addFileParams("files", fileList)
            .headers("Authorization", "Bearer $tokenID")
            .adapt(ObservableResponse())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer!!)
    }

    fun updateUserInfo(
        url: String?,
        mSelectList: List<String?>?,
        deviceCode: String?,
        nikeName: String?,
        observer: Observer<Response<String>>?
    ) {
        if (mSelectList == null && TextUtils.isEmpty(nikeName)) {
            return
        }
        val tokenID = App.application().getShareData().getString(BaseConfig.TOKEN_ID,"") as String
        if (mSelectList != null) {
            val fileList: MutableList<File> = ArrayList()
            for (path in mSelectList) {
                if (TextUtils.isEmpty(path)) {
                    continue
                }
                val file = File(path)
                fileList.add(file)
            }
            OkGo.post<String>(url)
                .converter(StringConvert())
                .isMultipart(true)
                .params("deviceCode", deviceCode)
                .addFileParams("file", fileList)
                .headers("Authorization", "Bearer $tokenID")
                .adapt(ObservableResponse())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer!!)
        } else {
            OkGo.post<String>(url)
                .converter(StringConvert())
                .isMultipart(true)
                .params("userName", nikeName)
                .params("deviceCode", deviceCode) //.addFileParams("files", fileList)
                .headers("Authorization", "Bearer $tokenID")
                .adapt(ObservableResponse())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer!!)
        }
    }
}